<?php
namespace App\Api\Helpers;

use App\Api\Helpers\CurlHttp;
use Illuminate\Support\Facades\Log;

/**
 * 移动运营商
 *
 */
trait MoveNumber{
    use CurlHttp;
    protected $url; // 请求移动运营商路由
    protected $errorParams;
    protected $errorReponse;
    protected $key;
    protected $encryptKey;

    public function __construct(){
        $this->url = "https://www.ha.10086.cn/uip/open/api";
        $this->errorParams = 200100;
        $this->errorReponse = 200200;
        $this->key = '!1qaz$RFV@';
        $this->encryptKey = "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC5lBhJ5EoRWi2HHQ+y5wMTQi9HvzNNKjMd2s8XL84gXv5gbm3PFntFWLiwusn+AHkmLBnNyVOFZDhu05cqDm1BNdKIj1QLeXmThkHBJHTVqA/vu9YcZQlcvsfxiv4u5JFYTWbIihgL3JV/4WNbW8Fa6CCywkPoQAew0FD352O/rz6K3ab+7hNEeoVM1zWYpG/kH87tr9UQLrD4OEMn+0mNq4IIQhTjOCPUTY+1De6ZyEJG13MFr8x3JFJdwlZCb/ubPCp+kjKHvj6Uh9ne8hFyjKaMNEu/3K38WtJDuOLdd4Wm5afcOiW2DIZdI4cHt2T4Y7wTghyEmuyffZz39jpNAgMBAAECggEABpAB6TWxtGS3wo3cUHuAosgnt97p8i6foJPB2FtliDYwNKvk0Gxi4OmUR01slBccMaWZmHILtPSL5B2jZxEb+4Yj8yRR9TNA817NmyKuPFnDjZ6FvkH6pMb5dxrETXPFic6Gdfet98ncCVSMNV6h9AYh3IzgylPCOPnMAzSxjakH1sEIgZJgRXiuYxMWM6eFlTX7gaXXDClGPsziBqRjPbArs1rqnG2ymZ2YhlKwFg3tzYN0Jae8yTQltVuoHJmec4l6Vq1xjAZrw7NkXpP3mmFV0nxtcyi1YOoIQYdzSFoAx7TTx0sJKRy7SNnwcBHqeCKyazLq94QYFnCRadNfGQKBgQDg+7UtqGiRWlO4onOcSOTSrLDAgs/XoiP02L5wfRZDI5YB7gEVsRtOUp+0+EJRs9BTg7W0/mX2t5DcqWQ6Q0WoTTkt2E1IkJtYfxc+r7DmxhEVvI1/AXdwN7+GS73BtTzqO1rkYxNR/B2nNQMU+Q2Mfn0759LahcIvXKLUS1f0YwKBgQDTKa7T0yWk/AoLzYAOGP2B8AaUNu6kLVNALV4XgCMkR5Y+MoMB3r3e++BuIFJttfP4yjW2P1E5VFmf6ALHmb4axKejD4BdyZSsKgFTwZ2ETir68oFS3WF5rf2G7gXXK4YDVbbO/zw7IE5EMFywSGIiL1hi5cyStP2N7L7Ee3ydjwKBgC25+vD0sYwZV7rHCchR6HAJOUNnUub4xWYWR16FjejHas2pmf7WqD4a/OrDKneAnG7c7imDKyYh2QeARiaxVY8HYv+2Xr7I5UnvSsIq40GEMCTC1d9iZOwh6INbEY41T9QrjCWvHVYkb8J0O9QfammLq9hpHancVcNaiJ2tUosRAoGBAMHjtDOr3RTwmAjeWIaZS6zTyDavedAmDhsPjSXm8l2Nndbeaox9CbqFbD2yT/2M5Me8ZDVDTkFlwiWh02uTL4tEpuiCg0uanHi42R8e2JNzcuOZaEW+IJKpv/D0/UflHthRC9plYdiogTT7cyAqVnEtJ+snNgA/T9HRYBjpijLhAoGAfjECDn3w8aswDQKpZbLsTmwQl5lvxGn1Is/BJsb4fc+aW++JhyYhmauoPtjJAXtqsHpFFAL1AfBVJNEjYRwU438A23ppTVLNcO4JwYvgigB9Glii35gsoaHwDAfMh10e4zbV6oq7c+swm8cLINzJLt11C6pdIzRaOwGy6Nb+EJw=";
    }

    /** RSA 加密 （移动）
     * @param $encryptKey
     *  @param $str
     * @return string
     */
    public function moveEncrypt($encryptKey, $str){

        $encryptKey = "-----BEGIN RSA PRIVATE KEY-----\n" . (wordwrap($encryptKey, 64, "\n", true))."\n" . "-----END RSA PRIVATE KEY-----\n";

        $pi_key =  openssl_pkey_get_private($encryptKey);

        openssl_private_encrypt($str, $encrypted, $pi_key);

        $encrypted = base64_encode($encrypted);

        return $encrypted;
    }




    /**
     * DES加密函数（移动）
     * 算法：des
     * 加密模式：ecb
     * 补齐方法：PKCS5
     * @param $input
     * @param $key
     * @return string
     */
    public function moveEncryptForDES($input, $key)
    {
        $data = bin2hex(openssl_encrypt($input, 'DES-ECB', $key,OPENSSL_RAW_DATA));
        return $data;
    }




    /**
     * DES解密函数（移动）
     * 算法：des
     * 加密模式：ecb
     * 补齐方法：PKCS5
     * @param $input
     * @param $key
     * @return string
     */
    public function moveDecryptForDES($input, $key)
    {
        $input = hex2bin($input);
        $data = openssl_decrypt($input, 'DES-ECB', $key,OPENSSL_RAW_DATA);
        $data = rtrim($data);
        return $data;
    }

    /**
     * 移动系统参数
     * @param string  $code  接口编码
     *
     * @return array
     */
    public function getSystemParams($code){
        if(!$code){
            return false;
        }

        $return_data = [
            'busiCode'   => $code,
            'sourceId'   => "1031",
            'busiSerial' => "1031".date('YmdHis', time()).rand(100000, 999999), // 业务流水
            'format'     => 'json',
        ];

        // 加密字符串 系统标识+接口编码+操作流水+|+时间戳(yyyy-mm-dd hh24:mi:ss)
        $sign_str = $return_data['sourceId'].$return_data['busiCode'].$return_data['busiSerial'].'|'.date('Y-m-d H:i:s', $_SERVER["REQUEST_TIME"]);
        $sign = $this->moveEncrypt($this->encryptKey, $sign_str);
        $return_data['sign'] = $sign;

        return $return_data;
    }

    /**
     * 一证五号查询
     * @param string $code 请求方法名
     * @param string $sourceId 请求方法编号
     * @param string $name     开号用户名
     * @param string $cardno   开号身份证号
     *
     * @return array
     */
    public function cardPhoneNumber($code, $name, $cardno){
        $returnCode = 200;
        $returnData = [];
        if (!$code || !$name || !$cardno) {
            return $this->returnParams($this->errorParams, '参数有误', $returnData);
        }
        $systemParams = $this->getSystemParams($code);
        $bodyParams = [
            "certNo"   => $this->moveEncryptForDES($name, $this->key),
            "custName" => $this->moveEncryptForDES($cardno, $this->key)
        ];

        $data = $this->curlMove($systemParams, $bodyParams);
        if( $data ){
            $returnCode = $data['code'];
            $returnData = $data['data'] ? $this->moveDecryptForDES($data['data']["entryData"], $this->key) : [];
        }

        return self::returnParams($returnCode, '', $returnData);
    }

    /**
     * 获取移动运营商号池
     * @param string $code 请求方法名
     * @param string $partId 请求号池归属地
     *
     * @return array
     */
    public function getPhoneNumber($code, $partId){
        $returnCode = 200;
        $returnData = [];
        if (!$code || !$partId) {
            return $this->returnParams($this->errorParams, '参数有误', $returnData);
        }
        $systemParams = $this->getSystemParams($code);
        $bodyParams = ['cardRegion'=> $partId];
        Log::info('取移动运营商号池入参', $bodyParams);
        $data = $this->curlMove($systemParams, $bodyParams);
        Log::info('取移动运营商号池出参', $data);
        if( $data ){
            $returnCode = $data['code'];
            $returnData = $data['data'];
        }


        return $this->returnParams($returnCode, '', $returnData);
    }

    /**
     * 套餐查询
     * @param string $code 请求方法名
     *
     * @return array
     */
    public function getPhoneMeal($code){
        $returnCode = 200;
        $returnData = [];
        if (!$code ) {
            return $this->returnParams($this->errorParams, '参数有误', $returnData);
        }
        $systemParams = $this->getSystemParams($code);
        $bodyParams = ['key'=> '123456'];
        $data = $this->curlMove($systemParams, $bodyParams);
        if( $data ){
            $returnCode = $data['code'];
            $returnData = $data['data'];
        }


        return $this->returnParams($returnCode, '', $returnData);
    }

    /**
     * 证件文字识别接口
     * @param string $code 请求方法名
     * @param string $img_base64  图片oss存储地址
     * @param string $img_type  图片类型  Z代表正面，F代表反面
     * @param string $phone_num  用户开户手机号
     *
     * @return string
     */
    public function cardDiscern($code, $img_base64, $img_type, $phone_num, $busi=''){
        $returnCode = 200;
        $returnData = [];
        $log = [
            '$code' => $code,
            '$img_base64' => strlen($img_base64),
            '$img_type' => $img_type,
            '$phone_num' => $phone_num,
            '$busi' => $busi
        ];
        Log::info('证件文字识别接口入参', $log);
        if (!$code || !$img_base64 || !$img_type || !$phone_num) {
            return $this->returnParams($this->errorParams, '参数有误', $returnData);
        }
        $systemParams = $this->getSystemParams($code);
        if($busi == '') $busi = time();
        $bodyParams = [
            "busiSeq"  => $busi,
            "picType"  => $img_type,
            "billId"   => $phone_num,
            "busiType" => "1",
            "picFile"  => $img_base64,
        ];
        $data = $this->curlMove($systemParams, $bodyParams);

        Log::info('证件文字识别接口验证结果', $data);

        if( $data ){
            $returnCode = $data['code'];
            $returnData['json'] = $data['data'] ? $this->moveDecryptForDES($data['data']["entryData"], $this->key) : [];
            $returnData['busi'] = $busi;
        }

        return $this->returnParams($returnCode, 'success', $returnData);
    }

    /**
     * 人像对比接口
     * @param string $code 请求方法名
     * @param string $img_url  人像图片oss地址
     * @param string $phone_num  开户手机号
     * @param string $busi  证件识别时的流水号
     * @param string $name  用户真实姓名
     * @param string $cardno  用户身份证号
     *
     * @return array
     */
    public function personImgDiscern($code, $img_url, $phone_num, $busi, $name, $cardno){
        $returnCode = 200;
        $returnData = [];
        if (!$code || !$img_url || !$phone_num || !$busi || !$name || !$cardno) {
            return $this->returnParams($this->errorParams, '参数有误', $returnData);
        }
        $systemParams = $this->getSystemParams($code);
        $bodyParams = [
            "busiSeq"    =>  $busi,
            "custName"   => $this->moveEncryptForDES($name, $this->key),
            "custCertNo" => $this->moveEncryptForDES($cardno, $this->key),
            "billId"     => $phone_num,
            "busiType"   => "1",
            "picFile"    => $img_url,
        ];

        $data = $this->curlMove($systemParams, $bodyParams);
        if( $data ){
            $returnCode = $data['code'];
            $returnData = $data['data'] ?? [];
        }

        return $this->returnParams($returnCode, '', $returnData);
    }

    /**
     * 创建订单  预占号
     * @param string $code 请求方法名
     * @param string $region    开号归属地
     * @param string $phone_num 手机号
     * @param string $busi      用户实名认证返回的在线流水号
     * @param string $name      开号用户名
     * @param string $cardno    开号用户身份证号
     * @param string $prod      套餐id
     * @param string $payment   支付金额
     * @param string $data      收货人快递信息
     *
     * @return array
     */
    public function createMoveOrders($code, $region, $phone_num, $name, $cardno, $prod, $payment,$data){
        $returnCode = 200;
        $returnData = [];
        if (!$code || !$region || !$phone_num || !$name || !$cardno || empty($data)|| !$prod) {
            writeLogs([$code, $region, $phone_num, $name, $cardno, $data, $prod ], '参数111', 'operator');
            return $this->returnParams($this->errorParams, '参数有误', $returnData);
        }
        $systemParams = $this->getSystemParams($code);
        writeLogs($systemParams, '系统参数', 'operator');
        $bodyParams = [
            "cardSvcnum"     =>  $phone_num,
            "cardRegion"     =>  $region, // 号码归属地
            "userTel"        =>  $this->moveEncryptForDES($data['tel'], $this->key), // 快递联系方式
            "province"       =>  $data['province'],
            "city"           =>  $data['city'],
            "county"         =>  $data['county'],
            "town"           =>  $data['town'],
            "address"        =>  $data['address'],
            "outProdId"      =>  $prod, // 套餐id
            "payAmount"      =>  intval($payment*100), // 支付金额 分
            "havecardType"   =>  "1", // 配送方式  送货上门
            "outOrderid"     =>  $data['order_id'], // 外部订单id
            "contactsname"   =>  $this->moveEncryptForDES($data['contactsname'], $this->key), // 收货人
            "useridNum"      =>  $this->moveEncryptForDES($cardno, $this->key), // 身份证号
            "userName"       =>  $this->moveEncryptForDES($name, $this->key),
            "picnamerpath"   =>  $data['picnamepath'],
            "busiSeq"        =>  $data['transaction_id'],
        ];
        writeLogs($bodyParams, '请求体参数', 'operator');
        $data = $this->curlMove($systemParams, $bodyParams);
        writeLogs($data, '请求预占号返回result', 'operator');
        if( $data ){
            $returnCode = $data['code'];
            $returnMessage = $data['message'];
            $returnData = $data['data'] ? $data['data'] : [];
        }

        return $this->returnParams($returnCode, $returnMessage, $returnData);
    }

    /**
     * 订单查询
     * @param string $code 请求方法名
     *
     * @return array
     */
    public function getOrderStatus($code){
        $returnCode = 200;
        $returnData = [];
        if (!$code ) {
            return $this->returnParams($this->errorParams, '参数有误', $returnData);
        }
        $systemParams = $this->getSystemParams($code);
        $bodyParams = ['key'=> '123456'];
        $data = $this->curlMove($systemParams, $bodyParams);
        if( $data ){
            $returnCode = $data['code'];
            $returnData = $data['data'];
        }


        return $this->returnParams($returnCode, '', $returnData);
    }

    /**
     * 订单状态同步成功反馈
     * @param string $changeid  同步id
     *
     * @return array
     */
    public function syncOrderSuccess($changeid){
        $code = 'UIP_CARD_STATECHANGERESULT';
        $returnCode = 200;
        $returnData = [];
        if (!$code ) {
            return $this->returnParams($this->errorParams, '参数有误', $returnData);
        }
        $systemParams = $this->getSystemParams($code);
        $bodyParams = ['changeId'=> $changeid];
        $data = $this->curlMove($systemParams, $bodyParams);
        if( $data ){
            $returnCode = $data['code'];
            $returnData = $data['data'];
        }


        return $this->returnParams($returnCode, '', $returnData);
    }

    /**
     * 退款接口
     * @param string $orderid 运营商订单id
     *
     * @return array
     */
    public function refund($orderid){
        $code = 'UIP_CARD_CHECKREFUND';
        $returnCode = 200;
        $returnData = [];
        if (!$code ) {
            return $this->returnParams($this->errorParams, '参数有误', $returnData);
        }
        $systemParams = $this->getSystemParams($code);
        $bodyParams = ['outOrderid'=> $orderid];
        $data = $this->curlMove($systemParams, $bodyParams);
        if( $data ){
            $returnCode = $data['code'];
            $returnData = $data['data'];
        }


        return $this->returnParams($returnCode, '', $returnData);
    }

    /**
     * 数据返回
     * @param int $code 返回码
     * @param string $msg 返回信息
     * @param array $data 数据信息
     *
     * @return array
     */
    public function returnParams($code, $msg='', $data=[]){
        return ['code'=> $code, 'msg'=> $msg, 'data'=>$data];
    }

    /**
     * 请求运营商
     * @param array $systemParams  请求运营商系统参数
     * @param array $bodyParams    请求运营商请求体参数
     *
     * @return array
     */
    public function curlMove($systemParams, $bodyParams){
        // 请求运营商接口获取号码
        $params_array = [
            "sysparams" => $systemParams,
            "busiparams" => $bodyParams,
        ];
        $params = json_encode($params_array);
        $result = $this->curlHttpRequest($this->url, 'POST', $params);
        Log::info('请求移动运营商返回结果', $result);
        if (!$result) {
            return ['code'=> $this->errorReponse, 'data'=> []];
        }
        //writeLogs($result, '请求预占号返回result', 'operator');
        //kang
//        if ( $result['code'] == 1 ) {
        if ( $result['code']) {
            // 调用成功
            $returnCode = 200;
            $returnMessage = 'success';
            $returnData = $result['data'];
        } else {
            $returnCode = $result['code'];
            $returnMessage = $result['message'];
            $returnData = $result['data'];
        }

        return ['code'=> $returnCode, 'message'=> $returnMessage, 'data'=> $returnData];
    }

    /**
     * 生成预占号订单
     * @param array $order_info  订单id
     *
     * @return string
     */
    public function make_phone_order($order_info){
        if( !$order_info->type ){
            return -1;die;
        }
        $data = [];
        if ($order_info->type == 1) {
            // 地址信息
            $address_info = $order_info->ad_city ? explode(',', $order_info->ad_city): '';
            $address_count = count($address_info);
            // 订单信息
            $express_data = [
                'order_id' => $order_info->order_sn,
                'tel' => $order_info->ad_phone,
                'province' => $address_info ? $address_info[0]: '',
                'city' => ($address_info && $address_info[1]) ? $address_info[1]: '',// 市
                'county' => ($address_info && ($address_count>=3)) ? $address_info[2]: $address_info[1], // 区
                'town' => ($address_info && ($address_count>=3)) ? $address_info[2]: $address_info[1], // 镇
                'address' => $order_info->ad_detail, // 详细地址
                'contactsname' => $order_info->ad_name, // 收货人
                'picnamepath' => $order_info->picnamepath, // 运营商返回信息
                'transaction_id' => $order_info->transaction_id, // 认证信息
            ];
            //writeLogs($express_data, '日志记录预占号订单数据-param', 'operator'); // 写入日志记录
            Log::info('生成预占号订单', $express_data);

            // 创建预占号订单
            $code = 'UIP_CARD_CREATEORDER_RT';
            $data = $this->createMoveOrders($code,$order_info->region,$order_info->phone,
                $order_info->ad_name,$order_info->ad_card,$order_info->prod_id,0,$express_data);
            writeLogs([$order_info->region, $order_info->phone,
                $order_info->ad_name, $order_info->ad_card, $order_info->prod_id], '日志记录预占号订单数据-params', 'operator'); // 写入日志记录
            writeLogs($data, '日志记录预占号订单数据-result', 'operator'); // 写入日志记录
        } elseif($order_info->type == 2) {
            // 联通创建预占号订单
            $data['code'] == 201;
        } else {
            // 电信创建预占号订单
            $data['code'] == 201;
        }
        if ($data['code'] == 200) {
            $returnData = [
                'code'     => 200,
                'order_id' => $data['data']['ORDERID'],
            ];
//            $order_id = $data['data']['ORDERID'];
        } else {
            $returnData = [
                'code'     => 201,
                'msg' => $data['msg'],
            ];
        }

        return $returnData;
    }
}
